package com.example.admin.brainwave;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.Log;

import com.example.admin.brainwave.dao.DataDB1;
import com.example.admin.brainwave.dao.DataDB2;
import com.example.admin.brainwave.utils.Const;
import com.example.admin.brainwave.utils.FileHelper;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class BluetoothServers extends Service {


    private final static String TAG = BluetoothServers.class.getSimpleName();
    private ServiceBinder serviceBinder;
    private static final UUID HC_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    private BluetoothAdapter mBluetoothAdapter = null;
    private BluetoothSocket mBluetoothSocket = null;
    private OutputStream outStream = null;
    private InputStream inStream = null;
    private boolean mBluetoothFlag = true;
    public boolean threadFlag = true;
    public boolean threadHandleData = true;
    BtThread btThread;
    OnServiceGetDataListener onServiceGetDataListener;
    private Handler handler;
    private boolean isFirst = true;
    private List<Integer> rawbyte = new ArrayList<>();
    private int pos = 0;
    FileHelper fileHelper;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        if (serviceBinder == null) {
            serviceBinder = new ServiceBinder();
        }
        return serviceBinder;
    }


    public class ServiceBinder extends Binder {
        public BluetoothServers getService() {
            return BluetoothServers.this;
        }
    }


    public interface OnServiceGetDataListener {
        void onDataChanged(double[] data);
    }

    public void setOnServiceGetDataListener(OnServiceGetDataListener onServiceGetDataListener) {
        this.onServiceGetDataListener = onServiceGetDataListener;
    }

    @Override
    public void onCreate() {
        fileHelper = new FileHelper(this);
        initBluetooth();
        handler = new Handler(getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                if (onServiceGetDataListener != null) {
                    if (msg.what == 1) {
                        onServiceGetDataListener.onDataChanged((double[]) msg.obj);
                    }
                }
            }
        };
    }


    private void initBluetooth() {
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    }


    public void bluetoothConnect(BluetoothDevice mBtDevice) {
        new Thread(() -> connectDevice(mBtDevice)).start();
    }


    private void connectDevice(BluetoothDevice mBtDevice) {
        try {
            mBluetoothSocket = mBtDevice.createRfcommSocketToServiceRecord(HC_UUID);
        } catch (IOException e) {
            e.printStackTrace();
            mBluetoothFlag = false;
            sendBroadcast("1");
        }
        mBluetoothAdapter.cancelDiscovery();
        try {
            mBluetoothSocket.connect();
        } catch (IOException e) {
            e.printStackTrace();
            sendBroadcast("1");
            try {
                mBluetoothSocket.close();
                mBluetoothFlag = false;
            } catch (IOException e1) {
                e1.printStackTrace();
                sendBroadcast("1");
            }
        }
        if (mBluetoothFlag) {
            try {
                inStream = mBluetoothSocket.getInputStream();
                outStream = mBluetoothSocket.getOutputStream();
                Log.i(TAG, "等待接受数据");
            } catch (IOException e) {
                sendBroadcast("1");
                e.printStackTrace();
            }
            btThread = new BtThread();
            btThread.start();
            sendBroadcast("0");
        }
    }

    public void sendBroadcast(String state) {
        Intent intent = new Intent();
        intent.putExtra("state", state);
        intent.setAction(Const.BLUETOOTH_CONNECT);
        sendBroadcast(intent);
    }

    public class BtThread extends Thread {

        @Override
        public void run() {
            while (threadFlag) {
                try {
                    readStream(inStream);
                    if (rawbyte == null) {
                        break;
                    }
                    //整个数据不到一个帧
                    if (rawbyte.size() < 40) {
                        continue;
                    }
                    while (threadHandleData) {
                        if (pos + 40 > rawbyte.size()) {
                            break;
                        }
                        if (rawbyte.get(pos) == 0Xa0 && rawbyte.get(pos + 1) == 0X30 && rawbyte.get(pos + 39) == 0Xc0) {
                            double[] SeriesPortLeadsDatas = new double[3];
                            for (int lead = 0; lead < 3; lead++) {
                                SeriesPortLeadsDatas[lead] = ((rawbyte.get(pos + 9 + 4 * lead) << 16)
                                        + (rawbyte.get(pos + 8 + 4 * lead) << 8)
                                        + (rawbyte.get(pos + 7 + 4 * lead) << 0));
                                //说明最高位符号位为1
                                if (SeriesPortLeadsDatas[lead] > Math.pow(2, 23)) {
                                    SeriesPortLeadsDatas[lead] = Math.pow(2, 24) - SeriesPortLeadsDatas[lead] + 1;                             //负数的补码转换为原码 取反加1
                                    SeriesPortLeadsDatas[lead] = -((SeriesPortLeadsDatas[lead] * 4.5 * Math.pow(10, 6)) / 24 / (Math.pow(2, 23) - 1));
                                } else {
                                    SeriesPortLeadsDatas[lead] = +((SeriesPortLeadsDatas[lead] * 4.5 * Math.pow(10, 6)) / 24 / (Math.pow(2, 23) - 1));  //正数原码为其补码，直接转换为电压值
                                }
                                //打日志 （ rawbyte[pos + 7 + 4 * lead] ，rawbyte[pos + 8 + 4 * lead] ，rawbyte[pos + 9 + 4 * lead] ）=> SeriesPortLeadsDatas[lead]
                                Log.i(TAG, rawbyte.get(pos + 7 + 4 * lead) + "," + rawbyte.get(pos + 8 + 4 * lead) + "," + rawbyte.get(pos + 9 + 4 * lead) + "=>" + SeriesPortLeadsDatas[lead]);
                            }
                            if (isFirst) {
                                DataDB1 dataDB1 = new DataDB1(SeriesPortLeadsDatas[0], SeriesPortLeadsDatas[1], SeriesPortLeadsDatas[2]);
                                MyApp.getDaoSession().getDataDB1Dao().insert(dataDB1);
                                //fileHelper.writeSDFile(dataDB1.toString(), "log1.txt");
                            } else {
                                DataDB2 dataDB2 = new DataDB2(SeriesPortLeadsDatas[0], SeriesPortLeadsDatas[1], SeriesPortLeadsDatas[2]);
                                MyApp.getDaoSession().getDataDB2Dao().insert(dataDB2);
                                //fileHelper.writeSDFile(dataDB2.toString(), "log2.txt");
                            }
                            pos += 40;
                            handler.sendMessage(handler.obtainMessage(1, SeriesPortLeadsDatas));
                            continue;
                        } else {
                            pos += 1;
                            continue;
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    break;
                }
            }
        }

    }

    public void setFirst(boolean first) {
        isFirst = first;
    }

    byte[] tempInputBuffer = new byte[260];

    public void readStream(InputStream inStream) throws Exception {
        int count = inStream.read(tempInputBuffer);
        if (count == -1) {
            return;
        }
        for (int i = 0; i < count; i++) {
            rawbyte.add(tempInputBuffer[i] & 0xff);
        }
    }


    public void writeSerial(String value) {
        try {
            outStream.write(value.getBytes());
            outStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        closeAll();
    }


    public void closeAll() {
        try {
            if (mBluetoothSocket != null) {
                writeSerial("uaisa");
                mBluetoothSocket.close();
                mBluetoothFlag = false;
            }
            if (btThread != null) {
                threadHandleData = false;
                threadFlag = false;
            }
            rawbyte.clear();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
